﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HslCommunication;
using HslCommunication.Profinet.Melsec;
using ClassLibrary1;
using System.IO;
using 扫码枪应用项目;
using System.Globalization;

namespace MYZNMarking
{
    public partial class FrmMain : Form
    {
        public static Action<bool[]> InAction { get; set; }
        public static Action<bool[]> OutAction { get; set; }
        public static Action<bool[]> XAction { get; set; }
        public static Action<string[]> NumAction { get; set; }
        private int ok = 0;
        private int ng = 0;
        private HistoryDataService historyDataService { get; set; } = new HistoryDataService();

        public FrmMain()
        {
            InitializeComponent();
            this.FormClosing += Form1_FormClosing;

        }

        private bool[] Inbools = new bool[20];
        private bool[] Outbools = new bool[20];
        private bool[] Xbools = new bool[24];
        string[] strings = new string[3];
        int number = 0;
        int Nnumber = 0;
        bool[] DBN = new bool[3];
        private void Form1_Load(object sender, EventArgs e)
        {
            CommonNaviButton_Click(this.naviButton2, null);
            Method.AddLog(0, "设备信息加载成功");
            this.lbl_User.Text = Program.User;
            PLCconnection();
            btn_Refresh_Click(null, null);
            DialogResult dialogResult = MessageBox.Show("请先选择产品信息", "系统提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
            if (dialogResult == DialogResult.Yes)
            {
                CommonNaviButton_Click(this.naviButton1, null);
            }
            FrmParamSet.ParamAction = new Action<bool[], int[]>((data1, data2) =>
            {
                OperateResult writeO = melsecMcNet.Write("M106", data1);
                OperateResult writeD = melsecMcNet.Write("D100", data2);

            });
            FrmInfo.CAction = new Action<bool[]>((data0) =>
            {
                OperateResult writeT = melsecMcNet.Write("M62", data0);
            });
            Task.Run(() =>
            {
                while (IsConnected)
                {
                    Invoke(new Action(() => label2.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " "
                + new CultureInfo("zh-CN").DateTimeFormat.GetDayName(DateTime.Now.DayOfWeek)));
                    Task.Delay(1000).Wait();
                }
            });

            Task.Run(() =>
            {
                while (IsConnected)
                    try
                    {
                        HslCommunication.OperateResult<bool[]> readIn = melsecMcNet.ReadBool("M6", 18);
                        HslCommunication.OperateResult<bool[]> readOut = melsecMcNet.ReadBool("M40", 15);
                        HslCommunication.OperateResult<bool[]> readX = melsecMcNet.ReadBool("M400", 24);
                        HslCommunication.OperateResult<bool[]> readRun = melsecMcNet.ReadBool("M61", 1);
                        HslCommunication.OperateResult<bool[]> readM = melsecMcNet.ReadBool("M52", 1);
                        HslCommunication.OperateResult<bool[]> readN = melsecMcNet.ReadBool("M430", 1);
                        if (readIn.IsSuccess && readOut.IsSuccess)
                        {
                            for (int i = 0; i < 18; i++)
                            {
                                Inbools[i] = readIn.Content[i];
                            }
                            for (int i = 0; i < 15; i++)
                            {
                                Outbools[i] = readOut.Content[i];
                            }
                            for (int i = 0; i < 24; i++)
                            {
                                Xbools[i] = readX.Content[i];
                            }
                            if (readM.Content[0] && !DBN[1])
                            {
                                Method.AddLog(1, "打标失败请检查打标设备!");
                                DBN[1] = true;
                            }
                            if (!readM.Content[0])
                            {
                                DBN[1] = false;
                            }
                            if (readN.Content[0] && !DBN[1])
                            {
                                Method.AddLog(2, "安全光栅或安全门被触发!");
                                DBN[1] = true;
                            }
                            if (!readN.Content[0])
                            {
                                DBN[1] = false;
                            }


                        }
                        Invoke(new Action(() =>
                        {

                            if (readRun.Content[0] != null)
                            {
                                lbl_Run.Text = readRun.Content[0] == true ? "设备运行中" : "设备等待中";
                                lbl_Run.BackColor = readRun.Content[0] == true ? Color.Lime : Color.Red;
                            }

                        }));
                        InAction?.Invoke(Inbools);
                        OutAction?.Invoke(Outbools);
                        XAction?.Invoke(Xbools);
                        Task.Delay(1000).Wait();
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
            });
            Task.Run(() =>
            {
                while (IsConnected)
                {
                    HslCommunication.OperateResult<bool[]> readOK = melsecMcNet.ReadBool("M66", 1);
                    if (readOK.Content[0])
                    {
                        HslCommunication.OperateResult<bool[]> readRes = melsecMcNet.ReadBool("M40", 1);//OK信号
                        OperateResult<float[]> readE = melsecMcNet.ReadFloat("D130", 1);
                        OperateResult<float[]> readn = melsecMcNet.ReadFloat("D410", 1);
                        Invoke(new Action(() =>
                        {
                            OperateResult writeResult = melsecMcNet.Write("M200", false);//写入完成信号
                            if (readRes.Content[0])
                            {
                                Storage();
                            }
                            number = Convert.ToInt32(txt_Number.Text);
                            if (readRes.Content[0])//收到OK信号后条码加1
                            {
                                Nnumber = number += 1;
                            }
                            FrontZeroPad(Nnumber);
                            txt_Number.Text = FrontZeroPad(Nnumber);
                            content = String.Concat(txt_Msg.Text, txt_Number.Text);
                            WriteToFile(path, content);
                            writeResult = melsecMcNet.Write("M200", true);
                        }));
                        strings[0] = readRes.Content[0] ? "OK" : "NG";
                        strings[1] = readE.Content[0].ToString();
                        strings[2] = readn.Content[0].ToString();
                        OperateResult WriteN = melsecMcNet.Write("M66", false);
                        melsecMcNet.Write("M200", false);
                        NumAction?.Invoke(strings);
                        Task.Delay(1000).Wait();
                    }
                }
            });
        }
        bool IsConnected;
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult dialogResult = MessageBox.Show("是否退出系统？", "退出系统", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (dialogResult == DialogResult.Yes)
            {
                //关闭串口和网口连接
                IsConnected = false;
                OperateResult connectClose = melsecMcNet.ConnectClose();
            }
            else
            {
                e.Cancel = true;
            }
        }

        MelsecMcNet melsecMcNet = new MelsecMcNet("192.168.0.151", 8000);
        private void PLCconnection()
        {
            try
            {
                OperateResult connectResult = melsecMcNet.ConnectServer();
                this.label8.Text = connectResult.IsSuccess ? "设备已连接" : "设备未连接";
                this.label8.BackColor = connectResult.IsSuccess ? Color.Lime : Color.Red;
                Method.AddLog(1, "PLC连接成功");
                IsConnected = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        string content;
        string path = "serial.txt";
        private void Storage()
        {
            string contend = ReadFromFile(path);
            HistoryData historyData = new HistoryData()
            {
                InsertTime = DateTime.Now,
                ProductNumber = contend,
                Result = "OK",
            };

            var list = historyDataService.GetAllHistoryDataByInfo(contend);

            if (list.Any(x => x.ProductNumber == contend))
            {
                historyDataService.DeleteHistoryData(historyData, contend);
                historyDataService.AddHistoryData(historyData);
            }

            else
            {
                historyDataService.AddHistoryData(historyData);
            }
        }


        private void btn_Refresh_Click(object sender, EventArgs e)
        {
            if (Program.User != "操作员")
            {
                content = ReadFromFile(path);
                string number = content.Substring(content.Length - 5, 5);
                string Mes = content.Substring(0, content.Length - number.Length);
                this.txt_Number.Text = number;
                this.txt_Msg.Text = Mes;
            }
            else
            {
                MessageBox.Show("没有操作权限！");
            }
        }


        private void btn_Save_Click(object sender, EventArgs e)
        {
            if (Program.User != "操作员")
            {
                content = String.Concat(txt_Msg.Text, txt_Number.Text);
                WriteToFile(path, content);
            }
            else
            {
                MessageBox.Show("没有操作权限");
            }
        }
        public static string FrontZeroPad(int fileNum)
        {
            if (fileNum >= 90000)
            {
                return fileNum.ToString();
            }
            else
            {
                return fileNum.ToString().PadLeft(5, '0');
            }
        }

        private void WriteToFile(string path, string content, bool isAppend = false)//追加，默认参数放最后面
        {
            FileStream fileStream = new FileStream(path, isAppend ? FileMode.Append : FileMode.Create);//是否追加选择方式       
            StreamWriter stringWriter = new StreamWriter(fileStream);
            stringWriter.Write(content);
            stringWriter.Close();
            fileStream.Close();
        }
        private string ReadFromFile(string path)
        {
            FileStream fileStream = new FileStream(path, FileMode.Open);
            StreamReader streamReader = new StreamReader(fileStream);
            string content = streamReader.ReadToEnd();
            streamReader.Close();
            fileStream.Close();
            return content;
        }

        private void CommonNaviButton_Click(object sender, EventArgs e)
        {
            if (sender is NaviButton2 navi)
            {
                if (Enum.IsDefined(typeof(ForNames), navi.TitleName))
                {
                    ForNames formNames = (ForNames)Enum.Parse(typeof(ForNames), navi.TitleName, true);
                    OpenForm(this.Main_Panel, formNames);
                    SetNaviButtonSelected(this.top_Panel, navi);
                    this.txt_Local.Text = Program.Loal;
                }
            }
        }
        /// <summary>
        /// 通用打开窗体
        /// </summary>
        /// <param name="mainPanel">容器空间</param>
        /// <param name="formNames">窗体枚举</param>
        private void OpenForm(Panel mainPanel, ForNames formNames)
        {
            int total = mainPanel.Controls.Count;
            int closeCount = 0;
            bool isFind = false;
            for (int i = 0; i < total; i++)
            {
                Control ct = mainPanel.Controls[i - closeCount];
                if (ct is Form frm)
                {
                    if (frm.Text == formNames.ToString())
                    {
                        frm.BringToFront();
                        isFind = true;
                        break;
                    }
                    //如果当前的Form不是我们需要操作的窗体,然后判断是否为固定窗体，如果不是则关闭，如果是则不做处理
                    else if ((ForNames)Enum.Parse(typeof(ForNames), frm.Text, true) >= ForNames.临界窗体)
                    {
                        frm.Close();
                        closeCount++;
                    }
                }
            }
            if (isFind == false)
            {
                Form frm = null;
                switch (formNames)
                {
                    case ForNames.生产信息:
                        frm = new FrmInfo();
                        Method.AddLog = ((FrmInfo)frm).AddLog;
                        break;

                    case ForNames.数据报表:
                        if (lbl_User.Text == "操作员")
                        {
                            MessageBox.Show("没有权限执行此操作！");
                            break;
                        }
                        frm = new FrmData();
                        break;
                    case ForNames.状态监控:
                        frm = new FrmOutput();

                        break;
                    case ForNames.参数配置:
                        frm = new FrmParamSet();
                        break;

                    default:
                        break;
                }
                if (frm != null)
                {
                    frm.TopLevel = false;
                    frm.FormBorderStyle = FormBorderStyle.None;
                    frm.Dock = DockStyle.Fill;
                    frm.Parent = mainPanel;
                    frm.BringToFront();
                    frm.Show();
                }
            }
        }

        /// <summary>
        /// 设置导航按钮选中
        /// </summary>
        /// <param name="topPanel">导航按钮容器</param>
        /// <param name="navibutton">导航按钮</param>
        private void SetNaviButtonSelected(Panel topPanel, NaviButton2 navibutton)
        {
            foreach (var item in topPanel.Controls.OfType<NaviButton2>())
            {
                item.IsSelected = false;
            }
            navibutton.IsSelected = true;

        }
        #region 减少闪烁
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0X02000000;
                return cp;
            }

        }

        #endregion

        private void btn_Set_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("是否更换使用用户", "提示", MessageBoxButtons.OKCancel) == DialogResult.OK)
            {

                Process.Start("MYZNMarking.exe");
                Process.GetCurrentProcess().Kill();
            }
        }

        private void btn_Exit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void 产量清零ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OperateResult WriteL = melsecMcNet.Write("D106", 0);
            OperateResult WriteN = melsecMcNet.Write("D310", 0);
        }



        private void btn_Safe_Click(object sender, EventArgs e)
        {
            HslCommunication.OperateResult<bool[]> readSa = melsecMcNet.ReadBool("M70", 1);

            if (readSa.Content[0])
            {
                OperateResult WriteSf = melsecMcNet.Write("M70", false);
                Invoke(new Action(() =>

                {
                    this.btn_Safe.BackColor = Color.White;
                }));

            }
            else
            {
                OperateResult WriteSf = melsecMcNet.Write("M70", true);
                Invoke(new Action(() =>

                {
                    this.btn_Safe.BackColor = Color.Lime;
                    Method.AddLog(1, "光栅已屏蔽");
                }));
            }
        }
    }
}
